首先我們要先了解到,關閉瀏覽器正常會終止所有活躍的 WebSocket 連接並向伺服器發送關閉信號。然而,在某些情況下(如網絡中斷、客戶端崩潰、網絡不穩定等),close 事件可能不會立即觸發。
不過測了一些方法但可能因為本地端的關係,除非找到本地與本地間要發生這種不主動通知close的觸發方式,所以我只能盡量實作看看
重新連接是基於client端與server端斷掉,所以client與server重新交握,而心跳則是因client端因各種原因導致斷開但卻沒有通知到server端,要讓server端主動去斷開
如果這個不修別人就很容易可以搞甚麼DDOS了,一直給你的server塞死掉的client最終附載不住癱瘓掉,當然簡單給他設個連接上限也可以防止伺服器炸掉,不過你的伺服器就會卡死或是禁止新的連接近來
下面大致展現一下心跳機制是如何運作的吧
server.js
wss.on("connection", (ws) => {
// 設置心跳機制
ws.isAlive = true; // 初始設置連接為活躍狀態
ws.on("pong", () => {
console.log("還活著唷");
ws.isAlive = true;
}); // 客戶端回應 pong 時,設置連接為活躍狀態
const interval = setInterval(() => {
console.log(wss.clients);
wss.clients.forEach((client) => {
if (client.isAlive === false) {
console.log("終止連接");
return client.terminate(); // 如果連接不活躍,終止連接
}
client.isAlive = false; // 暫時設置連接為不活躍
client.ping(); // 發送 ping 幀以檢查連接狀態
console.log("發送 ping 幀");
});
}, 3000); // 每 3 秒檢查一次連接狀態
ws.on("close", () => {
clearInterval(interval); // 連接關閉時,清除定時器
console.log("關掉囉");
});
});
解釋:
wss.clients可以看出你有多少個連接,如果有10個人向你連接則有10筆,而在每個交握中添加了isAlive的變數,然後對前端發送ping消息,如果前端沒給予回應則會關閉。
ping/pong
後端server發送ping訊號後,前端瀏覽器會自動用pong訊號接收並自動返回ping訊號,使得後端server的pong訊號可以觸發,從而控制isAlive這樣就可得知是否斷開連線了
ws.onopen = () => {
console.log("Connected to server");
// 客戶端定期發送心跳訊息
setInterval(() => {
// 確保 WebSocket 連線仍然是 OPEN 狀態
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: "heartbeat" }));
console.log("還活著");
}
}, 3000); // 每 3 秒發送一次心跳訊息
};
既然瀏覽器會自動幫我們回應pong訊息,那client幹嘛還要寫呢?
所以client也可不寫,但如果只靠瀏覽器的流程,可能就會少很多的訊息,如果你希望的是收到client的詳細訊息則可直接用計時器固定發些資訊給後端,後端再用message去接收判斷
不過也因為瀏覽器會自動去觸發因此js並無onping/onpong的指令,如果遇到client端需要自己寫,大概就是這樣運作的
原以為心跳只是單純刪除多餘的連結,後面想了想好像有資安問題就是塞一堆突然覺得挺有趣的,畢竟因為websocket會一直交握只要有一台電腦就可以輕鬆讓伺服器過載,但一般的fetch就需要大量的電腦一同攻擊才可能
不過應該也有檢查server負荷的方法就是了,避免使用有效連結讓伺服器卡死,但是比起沒有心跳能用殭屍方式塞爆,與用有效連結塞爆的server兩者的成本也會有導致攻擊方會不會扁你
不過我也非專業資安人士,只不過在寫的時候感覺websocket的持續連接好像會有這些問題,有問題請見諒哈哈
但也可從這些部分看出,Websocket雖然有者持續連接的好處在,但要做的各種防禦排錯處理等等都會很複雜,比起以往的單向傳輸還來的須注意更多就是了
下面內容轉自網站:https://valuementor.com/managed-security/understanding-web-sockets-attacks/
為了最大限度地降低 WebSocket 出現安全漏洞的風險,請遵循以下準則:
資安真的挺多的,至於WebSocket的DDoS是否有我想的那麼簡單也不好說,有機會在試試他的其他問題例如CSRF
今天就這樣囉